package de.blitzcoder.collide.gui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 *
 * @author blitzcoder
 */
public class TabbedDocumentManager extends DocumentManager implements ChangeListener {

    // The TabbedPane
    private JTabbedPane tabbedPane;

    // Holds the documents
    private ArrayList<Document> documents;

    public TabbedDocumentManager() {
        tabbedPane = new JTabbedPane();
        documents = new ArrayList<Document>();
        tabbedPane.addChangeListener(this);
    }

    @Override
    public void bringToFront(Document doc) {
        tabbedPane.setSelectedComponent(doc);
    }

    @Override
    public boolean removeDocument(Document doc) {
        if (doc.close()) {
            tabbedPane.remove(doc);
            documents.remove(doc);
            fireDocumentRemoved(doc);
            return true;
        }
        return false;
    }

    @Override
    public Document getCurrentDocument() {
        Component comp = tabbedPane.getSelectedComponent();
        return comp == null?null:(Document)comp;
    }

    @Override
    public Document[] getAllDocuments() {
        return documents.toArray(new Document[0]);
    }

    @Override
    public void finishDocumentInsertion(final Document doc) {
        
        final int tabIndex = documents.indexOf(doc);

        final DocumentTabComponent tabComp = new DocumentTabComponent(doc.getTitle(), doc.getIcon(), tabbedPane, tabIndex);

        tabbedPane.setComponentAt(tabIndex, doc);

        doc.documentInserted(tabComp.getPopupMenu());

        tabbedPane.setTabComponentAt(tabIndex, tabComp);

        tabComp.addCloseAllListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                removeAllDocuments();
            }
        });

        tabComp.addCloseOtherListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                removeOtherDocuments(doc);
            }
        });

        tabComp.addCloseListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                removeDocument(doc);
            }
        });

        doc.addUpdateListener(new Document.UpdateListener() {
            public void update(final Document doc) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        tabbedPane.setTitleAt(tabIndex, doc.getTitle());
                        tabbedPane.setToolTipTextAt(tabIndex, doc.getToolTip());
                        tabbedPane.setIconAt(tabIndex, doc.getIcon());
                        tabComp.setTitle(doc.getTitle());
                    }
                });
            }
        });

        fireDocumentAdded(doc);
        fireDocumentSelected(doc);

    }

    @Override
    public void startDocumentInsertion(Document doc) {
        // Try to get some first titles and stuff
        String title = doc.getTitle();
        Icon icon = doc.getIcon();
        String toolTip = doc.getToolTip();

        if (title == null) {
            title = "Loading...";
        }

        if (toolTip == null) {
            toolTip = "Loading...";
        }

        JLabel label = new JLabel("Loading...");

        tabbedPane.addTab(title, icon, label, toolTip);
        
        documents.add(doc);
        tabbedPane.setSelectedComponent(label);

    }

    @Override
    public JComponent getComponent() {
        return tabbedPane;
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        Component comp = tabbedPane.getSelectedComponent();
        if (comp != null && comp instanceof Document) {
            Document doc = (Document)comp;
            fireDocumentSelected(doc);
            doc.focus();
        }
    }

    @Override
    public int getCurrentDocumentIndex() {
        return tabbedPane.getSelectedIndex();
    }
}
